package org.example.study.nio;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestFileChannel {

    @Test
    public void testWrite() throws IOException {
        String str = "hello, 测试FileChannel";
        //创建一个输出流 -> channel
        FileOutputStream fileOutputStream = new FileOutputStream("file01.txt");

        //通过 fileOutputStream 获取对应的 FileChannel
        //这个 fileChannel 真实类型是 FileChannelImpl
        FileChannel fileChannel = fileOutputStream.getChannel();

        //创建一个缓冲区 ByteBuffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        //将 str 放入 byteBuffer
        byteBuffer.put(str.getBytes());

        //对 byteBuffer 进行 flip
        byteBuffer.flip();

        //将 byteBuffer 数据写入到 fileChannel
        fileChannel.write(byteBuffer);
        fileOutputStream.close();
    }

    @Test
    public void testRead() throws IOException {
        //创建文件的输入流
        File file = new File("file01.txt");
        FileInputStream fileInputStream = new FileInputStream(file);

        //通过 fileInputStream 获取对应的 FileChannel -> 实际类型 FileChannelImpl
        FileChannel fileChannel = fileInputStream.getChannel();

        //创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int)file.length());

        //将通道的数据读入到 Buffer
        fileChannel.read(byteBuffer);

        //将 byteBuffer 的字节数据转成 String
        System.out.println(new String(byteBuffer.array()));

        fileInputStream.close();
    }

    @Test
    public void testCopyFile() throws IOException {

        FileInputStream fileInputStream = new FileInputStream("file01.txt");
        FileOutputStream fileOutputStream = new FileOutputStream("file02.txt");
        FileChannel channel = fileInputStream.getChannel();
        FileChannel channel1 = fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(5);

        while (true) {
            byteBuffer.clear(); // 通过clear方法对position、limit 和 mark 进行复位。
            int read = channel.read(byteBuffer); // 通道往缓冲区里写入数据。
            if (read == -1)
                break;

            byteBuffer.flip();
            channel1.write(byteBuffer); // 从缓冲区里读取数据，再写入通道。
        }

        fileInputStream.close();
        fileOutputStream.close();
    }

    @Test
    public void testCopyFile2() throws IOException {

        FileInputStream fileInputStream = new FileInputStream("file01.txt");
        FileOutputStream fileOutputStream = new FileOutputStream("file03.txt");
        FileChannel src = fileInputStream.getChannel();
        FileChannel dest = fileOutputStream.getChannel();

        dest.transferFrom(src, 0, src.size());

        fileInputStream.close();
        fileOutputStream.close();
    }

}
